package com.kpmg.datalake.schedule.utils;

import com.alibaba.fastjson.JSONObject;
import com.kpmg.datalake.schedule.enums.ScheduleExecStatusEnum;
import com.kpmg.datalake.schedule.model.ScheduleJob;
import com.kpmg.datalake.schedule.model.ScheduleJobLog;
import com.kpmg.datalake.schedule.service.IScheduleJobLogService;
import com.kpmg.datalake.schedule.service.IScheduleJobService;
import com.kpmg.datalake.schedule.service.ScheduleExecuteService;
import com.kpmg.datalake.schedule.service.impl.ScheduleMangerServiceImpl;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Alex.zhao [alex.zhao@kpmg.com]
 * @since Created on azhao6 on 2018-08-09 21:50:57
 */
public class TaskUtils {

  public static final String SCHEDULE_JOB = "scheduleJob";
  private static final Logger logger = LoggerFactory.getLogger(TaskUtils.class);
  private static IScheduleJobService scheduleJobService = null;
  private static IScheduleJobLogService scheduleJobLogService = null;

  private TaskUtils() {
  }

  /**
   * 通过反射调用scheduleJob中定义的方法
   *
   * @param scheduleJob scheduleJob
   */
  public static void invokeMethod(ScheduleJob scheduleJob)
      throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    ScheduleExecuteService scheduleExecuteService = null;
    if (StringUtils.isNotBlank(scheduleJob.getJobAction())) {
      scheduleExecuteService = (ScheduleExecuteService) ScheduleMangerServiceImpl
          .getBean(scheduleJob.getJobAction());
      //如果spring 容器中不存在bean 则通过newInstance获取 java 对象
      if (scheduleExecuteService == null) {
        Class clazz = Class.forName(scheduleJob.getJobAction());
        scheduleExecuteService = (ScheduleExecuteService) clazz.newInstance();
      }
    }
    if (scheduleExecuteService == null) {
      logger.error("任务名称 = [{}]---------------未启动成功，请检查是否配置正确！！！", scheduleJob.getJobName());
      return;
    }
    scheduleExecuteService.execute(scheduleJob);
  }

  /**
   * 新增任务日志 scheduleJob
   *
   * @param scheduleJob scheduleJob
   * @param beginTime beginTime
   */
  public static ScheduleJobLog insertScheduleLog(ScheduleJob scheduleJob, Long beginTime) {
    ScheduleJobLog scheduleJobLog = new ScheduleJobLog();
    scheduleJobLog.setJobId(scheduleJob.getJobId());
    scheduleJobLog.setJobName(scheduleJob.getJobName());
    scheduleJobLog.setJobDesc(scheduleJob.getJobDesc());
    scheduleJobLog.setJobCron(scheduleJob.getJobCron());
    scheduleJobLog.setExecStatus(ScheduleExecStatusEnum.RUNNING.getCode());
    scheduleJobLog.setExecParam(JSONObject.toJSONString(scheduleJob));
    scheduleJobLog.setBeginTime(new Date(beginTime));
    if (scheduleJobLogService == null) {
      scheduleJobLogService = ScheduleMangerServiceImpl.getBean(IScheduleJobLogService.class);
    }
    scheduleJobLogService.insert(scheduleJobLog);
    return scheduleJobLog;
  }

  /**
   * 处理任务日志
   *
   * @param scheduleJob 任务日志
   * @param scheduleJobLog scheduleJobLog
   * @param isError 错误信息
   * @param e 错误
   */
  public static void updateScheduleLog(ScheduleJob scheduleJob, ScheduleJobLog scheduleJobLog,
      Boolean isError, Exception e) {
    scheduleJobLog.setExecStatus(
        isError ? ScheduleExecStatusEnum.FAILED.getCode() : ScheduleExecStatusEnum.DONE.getCode());
    if (isError) {
      StringBuilder sb = new StringBuilder();
      sb.append(e.getMessage());
      sb.append(" \r\n ");
      for (StackTraceElement stackTraceElement : e.getStackTrace()) {
        sb.append(stackTraceElement);
        sb.append(" \r\n ");
      }
      scheduleJobLog.setExecResult(sb.toString());
    }
    long endTime = System.currentTimeMillis();
    scheduleJobLog.setEndTime(new Date(endTime));
    scheduleJobLog.setCostTime(endTime - scheduleJobLog.getBeginTime().getTime());
    //更新错误信息
    if (scheduleJobLogService == null) {
      scheduleJobLogService = ScheduleMangerServiceImpl.getBean(IScheduleJobLogService.class);
    }
    scheduleJobLogService.updateById(scheduleJobLog);
    //更新最近执行时间
    if (scheduleJobService == null) {
      scheduleJobService = ScheduleMangerServiceImpl.getBean(IScheduleJobService.class);
    }
    scheduleJob.setLatelyTime(new Date(endTime));
    scheduleJobService.updateById(scheduleJob);

  }


}
